/*
    生命周期demo1 说明
 */
pub fn test() {
    let result;
    let result2;
    let result3;
    let result4;
    let str2 = "abcd 2";
    let str4 = String::from("abcd 1");
    {
        //String::from将字符串字面量从内存中的代码区（ROData段）复制一份到堆，并用栈上分配的变量指向堆内存。
        //Box 可以强制指定分配到堆
        //比如说String::from 会在堆上开辟空间,传递的话就是引用传递
        let str1 = String::from("abcd 1");
        //不可变的字符串切片，通常是对字符串字面量的引用。字符串字面量（例如 "123"）在编译时将被放置在二进制的只读部分，因此它是栈分配的，而不是堆分配的
        // 一个指向字符串字面量的不可变引用，这个字面量是存储在编译后的只读数据段中，因此它是栈分配的。
        //字符串 str3 是一个字符串字面量，字面量在 Rust 中具有 'static 生命周期。这意味着它在程序的整个运行期间都有效，并且不受任何作用域的限制
        let str3 = "abcd 3";
        result = scopeDemo(&str1.as_str(), str2, str3);
        result2 = scopeDemo(&str4.as_str(), str2,str3);
        result3 = scopeDemo2(&str1.as_str(), str2, str3);
        result4 = scopeDemo2(&str4.as_str(), str2,str3);
        println!("scope in {} {}",result,result2);
        println!("scope in {} {}",result3,result4);
    }
    //str1在出上面范围时候生命周期已经结束, 但是result变量在范围外还有引用,而result生命周期='a标记得传递变量中最短那个也就是str1的生命周期所以这里就会报错
    // println!("scope {}",result);

    //result2 生命周期标记的'a
    println!("scope out {}",result2);
    println!("scope out {} {}",result3,result4);
}

/*
    'a ('b 和泛型类似可以'小写字母 标记多个) 标识生命周期,
    如果标记被多处引用那么会取生命周期最短那个作为检查
    由于我返回的参数标记作用域也是'a 所以返回的值作用域='a标记中最短的作用域
 */
fn scopeDemo<'a>(x: &'a str,y: &'a str,j: &'a str) -> &'a str{
    println!("scope func: {} {} {}",x,y,j);
    return x
}
/*
    只有返回引用时候才需要关注生命周期
 */
fn scopeDemo2(x: &str,y: &str,j: &str) -> String{
    return String::from(x)
}